package com.open.source.ams.metadata;

import static org.springframework.util.ResourceUtils.CLASSPATH_URL_PREFIX;

import com.open.source.ams.DemoImportModel;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import org.springframework.util.ResourceUtils;

/**
 * @author ZonLen since on 2022/3/11 下午1:18
 */
public class GenerateImportModelClass {

  public static void main(String[] args)
      throws ClassNotFoundException, IOException, URISyntaxException, IllegalAccessException, InstantiationException {
    final ImportModelMetadata demoImport = new ImportModelMetadata("DemoImport",
        DemoImportModel.class);
    final Class<?> aClass = generateImportModelClass(demoImport);
    System.out.println(aClass);
    final Object o = aClass.newInstance();
    System.out.println(o);
  }

  /**
   * 根据元数据生成导入类
   */
  public static Class<?> generateImportModelClass(
      ImportModelMetadata importModelMetadata)
      throws IOException, URISyntaxException, ClassNotFoundException {
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    try (final StandardJavaFileManager manager = compiler
        .getStandardFileManager(null, null, null)) {
      GenerateJavaFileObject generateJavaFileObject = new GenerateJavaFileObject(
          new URI(importModelMetadata.simpleClassName() + ".java"), JavaFileObject.Kind.SOURCE,
          importModelMetadata.classCode());
//      final String classPath = System.getProperty("user.dir") + "/target/classes";
      final List<String> options = new ArrayList<>();
      options.add("-d");
      options.add(ResourceUtils.getURL(CLASSPATH_URL_PREFIX).getPath());
      final JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, options, null,
          Collections.singleton(generateJavaFileObject));
      task.call();
    }
    return GenerateImportModelClass.class.getClassLoader()
        .loadClass(importModelMetadata.getClassName());
  }


  static class GenerateJavaFileObject extends SimpleJavaFileObject {

    private final String content;

    public GenerateJavaFileObject(URI uri, Kind kind, String content) {
      super(uri, kind);
      this.content = content;
    }

    @Override
    public CharSequence getCharContent(boolean ignoreEncodingErrors) {
      return this.content;
    }
  }

}
